from datetime import datetime, timedelta, timezone
import jwt
from fastapi import HTTPException
from passlib.context import CryptContext
from starlette import status

from backend.config.settings import settings

# 密码哈希
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def get_guest_user() -> dict:
    return {
        "user_id": 0,
        "username": "guest",
        "role": "游客",
    }

# 验证明文和哈希是否匹配
def verify_password(plain_password: str, hashed_password: str) -> bool:
    return pwd_context.verify(plain_password, hashed_password)

# 生成哈希
def get_password_hash(password: str) -> str:
    return pwd_context.hash(password)

# JWT工具
def create_access_token(data: dict, expires_delta: timedelta = None)-> str:
    now = datetime.now(timezone.utc)
    payload = {
        # 过期时间
        "exp": now + (expires_delta or timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)),
        # 发行时间
        "iat": now,
        # 生效时间
        "nbf": now,
        "data": data
    }
    encoded_jwt = jwt.encode(payload, settings.JWT_SECRET_KEY, algorithm=settings.JWT_ALGORITHM)
    return encoded_jwt

# 验证JWT
def verify_token(token: str) -> dict:
    try:
        payload = jwt.decode(token, settings.JWT_SECRET_KEY, algorithms=[settings.JWT_ALGORITHM])
        # 将时间戳换成带时区的datetime
        exp_timestamp = payload["exp"]
        exp_datetime = datetime.fromtimestamp(exp_timestamp, tz=timezone.utc)
        now = datetime.now(timezone.utc)

        if now > exp_datetime:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token已过期")
        # print( payload["data"])
        return payload["data"]
    except jwt.PyJWTError as e:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=f"Token验证失败{str(e)}")